package com.luhuiguo.cms.client;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.luhuiguo.cms.shared.event.ServerStatusEvent;
import com.luhuiguo.cms.shared.event.ServerStatusEvent.ServerStatus;
import com.luhuiguo.gwt.dispatcher.client.DispatcherAsync;
import com.luhuiguo.gwt.presenter.client.Display;
import com.luhuiguo.gwt.presenter.client.EventBus;
import com.luhuiguo.gwt.security.shared.exception.GwtSecurityException;

public abstract class AppCallback<T> implements AsyncCallback<T> {

    private DispatcherAsync dispatcher = null;

    private EventBus eventBus = null;

    private ServerStatusEvent available = new ServerStatusEvent(ServerStatus.Available);

    private ServerStatusEvent unavailable = new ServerStatusEvent(ServerStatus.Unavailable);

    @SuppressWarnings("unused")
    private Display display = null;

    @Inject
    public AppCallback(DispatcherAsync dispatcher, EventBus bus, Display display) {
        this(dispatcher, bus);
        this.display = display;
    }

    @Inject
    public AppCallback(DispatcherAsync dispatcher, EventBus bus) {
        this.dispatcher = dispatcher;
        this.eventBus = bus;
    }

    @Override
    public final void onFailure(Throwable caught) {
        if (caught instanceof GwtSecurityException) {
            onSecurityException((GwtSecurityException) caught);
        } else {
            eventBus.fireEvent(unavailable);
            onException(caught);
        }

    }

    @Override
    public final void onSuccess(T result) {

        eventBus.fireEvent(available);

        callback(result);
    }

    protected abstract void onSecurityException(final GwtSecurityException caught);

    protected abstract void onException(final Throwable caught);

    public abstract void callback(T result);

}
